////////////////////////////////////////////////////////////////////////
// This file is part of the simpleSID framework
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
//
// Copyright (c)Richard White, 2009
// See License.txt for a disclaimer of all warranties
// and licensing information

//Class for modelling ther 8580 filter its done like this as the 6581 is a head frak to understand.
class Filter
{
public:
	Filter();
	virtual ~Filter();
	
	void Reset();
	
	void SetClockFreq(float fClockFreq);
	
	//These are for setting the filter registers
	void SetFCLo(unsigned char byFCLo);
	void SetFCHi(unsigned char byFCHi);
	void SetResFilt(unsigned char byResFilt);
	void SetModeVol(unsigned char byModeVol);
	
	//These are higher level functions used for testing
	void SetFiltVoice1(bool bState);
	void SetFiltVoice2(bool bState);
	void SetFiltVoice3(bool bState);
	void SetFiltExt(bool bState);
	void SetVoice3Off(bool bState);
	void SetModeLP(bool bState);
	void SetModeBP(bool bState);
	void SetModeHP(bool bState);
	void SetVol(unsigned char byVol);
	void SetFreq(float fFreq);
	void SetRes(unsigned char byRes);

	void EnableFiler(bool bState);

	float Process(int iVoice1, int iVoice2, int iVoice3);

private:
	void SetQ();
	void SetW0();
	void MapFCtoFreq();
	
	float m_fClockFreq;
	
	static const float m_PI;
	
	//Variable for the filter
	float m_fW0Cache;
	float m_f1DivQ;

	unsigned short m_wFC; //This is the 11bit register of the freq
	float m_fFreq; //This will store the real value of the frequency of the cuttof

	unsigned char m_byFilt; //is a nibble in size really and selcts which voice is routed to the filter
	unsigned char m_byRes; //Q value as combined reg
	float m_fRes; //This is normalised Q
	
	//Thse are higher level view variables for what voices are routed to the filter
	bool m_bFiltV1;
	bool m_bFiltV2;
	bool m_bFiltV3;
	bool m_bFiltExt; // This will not be used but is here cause i said so incase

	bool m_bVoice3Off; //This is for disconnecting the output of voice 3 so it can be used for modulation
	bool m_bLP;
	bool m_bBP;
	bool m_bHP;

	unsigned char m_byMode; //This is the reg specifying how the filter operates
	unsigned char m_byVol; //This is a nibble in size
	float m_fVol; //Vol Normalised to 0-1
	
	float m_fK, m_fB; //These are used for mapping FC to a frequency

	float m_fVhp, m_fVbp, m_fVlp;

	bool m_bEnabled;

};